/* Public interface to the ENCx24J600 driver */

/* This driver is written largely for an ENC424J600 over the MODE 5 PSP
 * interface. Sorry! */

#define ENCX24J600_H

/* Constants for the Ethernet Link config byte */
#define E_LINK_AUTO 0x01
#define E_LINK_100FD 0x02
#define E_LINK_100 0x04
#define E_LINK_10FD 0x08
#define E_LINK_10 0x10

/* Constants for status return code from rx good check */
#define E_RX_GOOD 0x01
#define E_RX_CRC 0x02
#define E_RX_LONG 0x04
#define E_RX_TYPE 0x08
#define E_RX_BROADCAST 0x10
#define E_RX_MULTICAST 0x20
#define E_RX_VLAN 0x40

/* initalise the chip */
void encx24j600_init(void);

/* Configure link negotiation */
void encx24j600_set_linkneg(uint8_t mode);

/* Process interrupt */
void encx24j600_interrupt(void);

/* TX packets from TX slots. Eventually all code will use this instead,
   since it allows us to generate packets at will */

/* return a free TX slot */
uint8_t encx24j600_tx_freeslot(void);

/* prepend some data on to the existing slot */
uint8_t encx24j600_tx_prepend(uint8_t slot, uint8_t *pkt, uint16_t len);

/* write a single byte into the existing slot. given as offset into slot from
   *current* write head point (ie, offset into *your* header you just wrote */
uint8_t encx24j600_tx_write_slot(uint8_t slot, uint8_t data, uint16_t offset);

/* calculate CRC using DMA of some chunk of the slot. starts from 
   your current head */
uint16_t encx24j600_tx_crc_slot(uint8_t slot, uint16_t len, uint16_t seed);

/* copy and CRC unread RX data into the packet. This prepends from the
   current length, but most of the time I expect this will be the tail of
   the slot */
uint16_t encx24j600_tx_crcdma_slot(uint8_t slot, uint16_t length, uint16_t seed);

/* TX a completed slot. If not already marked ready, it will be. This means
   it will be retransmitted automatically if collisions cause an abort */
/* note: this returns before the TX is complete, as interrupt from chip
   will tell us when it's done */
void encx24j600_tx_slot(uint8_t slot);

/* Free a slot */
void encx24j600_slot_done(uint8_t slot);

/* return current payload length for a slot */
uint16_t encx24j600_slot_len(uint8_t slot);

/* TX full packet given in buffer */

/* Start a new packet TX, returns address of start */
uint16_t encx24j600_tx_start(void);

/* Append data to the existing packet, returns new address */
uint16_t encx24j600_tx_append(void *pkt, uint16_t len);

/* Calculate CRC on existing packet data already in TX buffer */
uint16_t encx24j600_tx_crc(uint16_t start, uint16_t len, uint16_t seed);

/* Calculate CRC while DMA copying some remaining packet data */
uint16_t encx24j600_tx_dmacrc(uint16_t len, uint16_t seed);

/* Straight DMA copy of all remaining packet data */
uint16_t encx24j600_tx_dma(void);

/* Straight write into buffer, one byte */
void encx24j600_tx_write(uint16_t addr, uint8_t value);

/* TX completion, and actual transmit */
void encx24j600_tx_complete(uint16_t start, uint16_t len);

/* RX from a waiting packet, returns 0 if nothing left to read,
   into the buffer */
uint16_t encx24j600_rx(void *pkt, uint16_t len);

/* Skip a number of RX octets waiting for us */
uint16_t encx24j600_rx_skip(uint16_t len);

/* Is there a packet waiting? */
uint8_t encx24j600_rx_waiting(void);

/* Discard remaining packet material for THIS packet, tidy up pointers */
void encx24j600_rx_complete(void);

/* Process header data, and return if packet is good */
uint8_t encx24j600_rx_good(void);

/* perform CRC on recently read data. This is mostly used for header
   CRC checking. Length of recent rx */
uint16_t encx24j600_rx_crc(uint16_t len);

/* generate a CRC for as yet unread data. If payload exceeds available 
   data in the packet, it will throw a warning. This is used by the UDP
   code which needs to checksum its payload */
uint16_t encx24j600_rx_crc_unread(uint16_t payload, uint16_t seed);

/* init the eeprom storage (currently null?) */
void encx24j600_eeprom_init(void);

